{
 "cells": [
  {
   "cell_type": "raw",
   "metadata": {
    "raw_mimetype": "text/restructuredtext"
   },
   "source": [
    ".. _nb_constraint_handling:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constraint Handling"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Inequality Constraints"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**If somebody is interested in implementing or willing to make contribution(s) regarding constraint handling of inequality constraints please let us know.\n",
    "The G problem is suite is already available to experiment with different algorithms. So far, mostly parameter-less constraint handling is used for our algorithms.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Equality Constraints"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We got a couple of questions of how equality constraints should be handled in a genetic algorithm. In general, functions without any smoothness are challenging to handle for genetic algorithms. An equality constraint is basically an extreme case, where the constraint violation is 0 at exactly one point and otherwise 1. \n",
    "\n",
    "Let us consider the following constraint $g(x)$ where $x$ represents a variable:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$g(x): x = 5$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An equality constraint can be expressed by an inequality constraint:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$g(x): |x - 5| \\leq 0$   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "or"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$g(x): (x-5)^2   \\leq 0$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, all of constraints above are very strict and make **most of the search space infeasible**. Without providing more information to the algorithm those constraint are very difficult to satisfy."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For this reason, the constraint can be smoothed by adding an epsilon to it and, therefore, having two inequality constraints:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$g'(x): 5 - \\epsilon \\leq x \\leq 5 + \\epsilon$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Also, it can be simply expressed in one inequality constraint by:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "$g'(x): (x-5)^2  - \\hat{\\epsilon} \\leq 0$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Depending on the $\\epsilon$ the solutions will be more or less close to the desired value. However, the genetic algorithm does not know anything about the problem itself which makes it difficult to handle and focus the search in the infeasible space."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Constraint Handling Through Repair**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A simple approach is to handle constraints through a repair function. This is only possible if the equation of the constraint is known. The repair makes sure every solution that is evaluated is in fact feasible. Let us consider the following example where \n",
    "the equality constraints need to consider more than one variable:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\\begin{align} \n",
    "\\begin{split}\n",
    "\\min \\;\\; & f_1(x) = (x_1^2 + x_2^2) \\\\ \n",
    "\\max \\;\\; & f_2(x) = -(x_1-1)^2 - x_2^2 \\\\[1mm]\n",
    "\\text{s.t.} \\;\\; & g_1(x_1, x_3) : x_1 + x_3 = 2\\\\[2mm]\n",
    "& -2 \\leq x_1 \\leq 2 \\\\\n",
    "& -2 \\leq x_2 \\leq 2 \\\\\n",
    "& -2 \\leq x_3 \\leq 2\n",
    "\\end{split}\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We implement the problem using by squaring the term and using an $\\epsilon$ as we have explained above. The source code for the problem looks as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "from pymoo.model.problem import Problem\n",
    "\n",
    "\n",
    "class MyProblem(Problem):\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__(n_var=3,\n",
    "                         n_obj=2,\n",
    "                         n_constr=1,\n",
    "                         xl=np.array([-2, -2, -2]),\n",
    "                         xu=np.array([2, 2, 2]))\n",
    "\n",
    "    def _evaluate(self, x, out, *args, **kwargs):\n",
    "        f1 = x[:, 0] ** 2 + x[:, 1] ** 2\n",
    "        f2 = (x[:, 0] - 1) ** 2 + x[:, 1] ** 2\n",
    "        g1 = (x[:, 0] + x[:, 2] - 2) ** 2 - 1e-5\n",
    "\n",
    "        out[\"F\"] = np.column_stack([f1, f2])\n",
    "        out[\"G\"] = g1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you might have noticed the problem has similar characteristics to problem in our getting started. \n",
    "Before a solution is evaluated a repair function is called. To make sure a solution is feasible, an approach would be to either set $x_3 = 2 - x_1$ or $x_1 = 2 - x_3$. Additionally, we need to consider that this repair might produce a variable to be out of bounds."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pymoo.model.repair import Repair\n",
    "\n",
    "class MyRepair(Repair):\n",
    "\n",
    "    def _do(self, problem, pop, **kwargs):\n",
    "        for k in range(len(pop)):\n",
    "            x = pop[k].X\n",
    "            if np.random.random() < 0.5:\n",
    "                \n",
    "                x[2] = 2 - x[0]\n",
    "                if x[2] > 2:\n",
    "                    val = x[2] - 2\n",
    "                    x[0] += val\n",
    "                    x[2] -= val\n",
    "                    \n",
    "            else:\n",
    "                x[0] = 2 - x[2]\n",
    "                if x[0] > 2:\n",
    "                    val = x[0] - 2\n",
    "                    x[2] += val\n",
    "                    x[0] -= val\n",
    "                \n",
    "                \n",
    "        return pop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now the algorithm object needs to be initialized with the repair operator and then can be run to solve the problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "====================================================================================================\n",
      "n_gen |  n_eval |   cv (min)   |   cv (avg)   |  n_nds  | delta_ideal  | delta_nadir  |   delta_f   \n",
      "====================================================================================================\n",
      "    1 |     100 |  0.00000E+00 |  0.00000E+00 |       5 |            - |            - |            -\n",
      "    2 |     200 |  0.00000E+00 |  0.00000E+00 |      11 |  0.055618092 |  0.382047403 |  0.096263287\n",
      "    3 |     300 |  0.00000E+00 |  0.00000E+00 |      17 |  0.025842665 |  0.072750314 |  0.046188141\n",
      "    4 |     400 |  0.00000E+00 |  0.00000E+00 |      26 |  0.002336572 |  0.002145159 |  0.016904647\n",
      "    5 |     500 |  0.00000E+00 |  0.00000E+00 |      40 |  0.001211493 |  0.033700365 |  0.011954721\n",
      "    6 |     600 |  0.00000E+00 |  0.00000E+00 |      52 |  0.000354057 |  0.074158937 |  0.013012498\n",
      "    7 |     700 |  0.00000E+00 |  0.00000E+00 |      72 |  0.000168691 |  0.004156081 |  0.005414720\n",
      "    8 |     800 |  0.00000E+00 |  0.00000E+00 |      93 |  0.000132785 |  0.002663388 |  0.003651793\n",
      "    9 |     900 |  0.00000E+00 |  0.00000E+00 |     100 |  0.001164071 |  0.066694097 |  0.003943605\n",
      "   10 |    1000 |  0.00000E+00 |  0.00000E+00 |     100 |  0.000020720 |  0.000020118 |  0.002154514\n",
      "   11 |    1100 |  0.00000E+00 |  0.00000E+00 |     100 |  0.000662304 |  0.034574202 |  0.002045963\n",
      "   12 |    1200 |  0.00000E+00 |  0.00000E+00 |     100 |  3.95143E-06 |  3.97141E-06 |  0.001283364\n",
      "   13 |    1300 |  0.00000E+00 |  0.00000E+00 |     100 |  5.98088E-07 |  0.003889728 |  0.001839679\n",
      "   14 |    1400 |  0.00000E+00 |  0.00000E+00 |     100 |  3.73314E-06 |  0.003870320 |  0.001734946\n",
      "   15 |    1500 |  0.00000E+00 |  0.00000E+00 |     100 |  9.00323E-07 |  9.04885E-07 |  0.001569638\n",
      "   16 |    1600 |  0.00000E+00 |  0.00000E+00 |     100 |  0.00000E+00 |  0.00000E+00 |  0.001456301\n",
      "   17 |    1700 |  0.00000E+00 |  0.00000E+00 |     100 |  0.00000E+00 |  0.00000E+00 |  0.001513338\n",
      "   18 |    1800 |  0.00000E+00 |  0.00000E+00 |     100 |  4.30341E-06 |  0.008379175 |  0.001564359\n",
      "   19 |    1900 |  0.00000E+00 |  0.00000E+00 |     100 |  0.00000E+00 |  0.00000E+00 |  0.001293048\n",
      "   20 |    2000 |  0.00000E+00 |  0.00000E+00 |     100 |  0.00000E+00 |  0.00000E+00 |  0.001524912\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 372,
       "width": 498
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from pymoo.algorithms.nsga2 import NSGA2\n",
    "\n",
    "algorithm = NSGA2(pop_size=100, repair=MyRepair(), eliminate_duplicates=True)\n",
    "\n",
    "from pymoo.optimize import minimize\n",
    "from pymoo.visualization.scatter import Scatter\n",
    "\n",
    "res = minimize(MyProblem(),\n",
    "               algorithm,\n",
    "               ('n_gen', 20),\n",
    "               seed=1,\n",
    "               verbose=True)\n",
    "\n",
    "plot = Scatter()\n",
    "plot.add(res.F, color=\"red\")\n",
    "plot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In our case it is easy to verify if the constraint is violated or not:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.\n",
      " 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.\n",
      " 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.\n",
      " 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.\n",
      " 2. 2. 2. 2.]\n"
     ]
    }
   ],
   "source": [
    "print(res.X[:, 0] + res.X[:, 2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you would like to compare the solution without a repair you will see how searching only in the feasible space helps:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "====================================================================================================\n",
      "n_gen |  n_eval |   cv (min)   |   cv (avg)   |  n_nds  | delta_ideal  | delta_nadir  |   delta_f   \n",
      "====================================================================================================\n",
      "    1 |     100 |  0.000035699 |  7.218880160 |       1 |            - |            - |            -\n",
      "    2 |     200 |  0.000035699 |  0.937483763 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "    3 |     300 |  0.000035699 |  0.098161741 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "    4 |     400 |  0.00000E+00 |  0.024978835 |       1 |  3.360562566 |  3.360562566 |  4.74270E+30\n",
      "    5 |     500 |  0.00000E+00 |  0.007024606 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "    6 |     600 |  0.00000E+00 |  0.001830226 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "    7 |     700 |  0.00000E+00 |  0.000759620 |       2 |  1.000000000 |  1.000000000 |  0.707106781\n",
      "    8 |     800 |  0.00000E+00 |  0.000303923 |       2 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "    9 |     900 |  0.00000E+00 |  0.000120410 |       2 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   10 |    1000 |  0.00000E+00 |  0.000059157 |       2 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   11 |    1100 |  0.00000E+00 |  0.000032714 |       2 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   12 |    1200 |  0.00000E+00 |  0.000018232 |       1 |  0.426183586 |  1.806170339 |  6.01738E+29\n",
      "   13 |    1300 |  0.00000E+00 |  8.43545E-06 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   14 |    1400 |  0.00000E+00 |  2.73546E-06 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   15 |    1500 |  0.00000E+00 |  1.84774E-07 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   16 |    1600 |  0.00000E+00 |  0.00000E+00 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   17 |    1700 |  0.00000E+00 |  0.00000E+00 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n",
      "   18 |    1800 |  0.00000E+00 |  0.00000E+00 |       1 |  0.018400947 |  0.018400947 |  2.60223E+28\n",
      "   19 |    1900 |  0.00000E+00 |  0.00000E+00 |       1 |  0.015017065 |  0.015017065 |  2.12368E+28\n",
      "   20 |    2000 |  0.00000E+00 |  0.00000E+00 |       1 |  0.00000E+00 |  0.00000E+00 |  0.00000E+00\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "image/png": {
       "height": 372,
       "width": 526
      },
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "algorithm = NSGA2(pop_size=100, eliminate_duplicates=True)\n",
    "\n",
    "res = minimize(MyProblem(),\n",
    "               algorithm,\n",
    "               ('n_gen', 20),\n",
    "               seed=1,\n",
    "               verbose=True)\n",
    "\n",
    "plot = Scatter()\n",
    "plot.add(res.F, color=\"red\")\n",
    "plot.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.99825371]\n"
     ]
    }
   ],
   "source": [
    "print(res.X[:, 0] + res.X[:, 2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here in fact the $\\epsilon$ term is necessary to find any feasible solution at all."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
